【AWS CDK】BucketDeploymentのpruneの設定値はデフォルトでtrueであることに注意しよう

【AWS CDK】BucketDeploymentのpruneの設定値はデフォルトでtrueであることに注意しよう

Clock Icon2024.07.26

データアナリティクス事業本部のueharaです。

今回は、AWS CDKの aws_s3_deployment.BucketDeployment のpropsである prune の設定値はデフォルトでtrueであることに注意しようという内容について説明させて頂きたいと思います。

はじめに

AWS CDKを利用している中で、ローカルファイルのS3へのアップロードに aws_s3_deployment.BucketDeployment を用いている方は多いのではないでしょうか。

ただ、裏でどのような処理が行われているか知らないままだと思わぬ落とし穴にハマってしまいます。

aws_s3_deploymentについて

公式のドキュメントに記載がありますが、 aws_s3_deployment モジュールは内部的にはLambda関数を作ってローカルファイルのアップロードを実現しています。

端的に流れを記載すると、以下のようになります。

  1. ソースのS3バケット(cdk deploy コマンドにより資材が配置) → Lambda一時ストレージ
  2. Lambdaの一時ストレージでファイルを展開・処理
  3. Lambda一時ストレージ → 宛先のS3バケット

ここで、 3. の実行は aws sync コマンドで実行されており、冒頭で述べたようにaws_s3_deployment.BucketDeployment のpropsである prune のデフォルト値は true となっているので、 aws sync --delete で実行されています。

どのような問題が起こるか?

例えば、 resources/dir1 というローカルのディレクトリをS3の cm-da-uehara バケットに target-path/dir1/ というprefixでアップロードする以下のコードをcdkで書いてみます。

const destinationBucket = s3.Bucket.fromBucketName(this, 'dest-bucket', 'cm-da-uehara');

// S3バケットにファイルをアップロード
new cdk.aws_s3_deployment.BucketDeployment(this, 's3-deploy-dir1', {
  sources: [cdk.aws_s3_deployment.Source.asset("resources/dir1")],
  destinationBucket:  destinationBucket,
  destinationKeyPrefix: 'target-path/dir1/',
});

cdk deploy コマンドによりデプロイが完了すると、以下の通りS3にファイルがアップロードされます。

20240726_cdk_s3_01

次に、 同じS3バケットに対し target-path/ というprefixで resources/dir2 のディレクトリファイルをアップロードする処理を追記します。

const destinationBucket = s3.Bucket.fromBucketName(this, `dest-bucket`, 'cm-da-uehara');

// S3バケットにファイルをアップロード
new cdk.aws_s3_deployment.BucketDeployment(this, `s3-deploy-dir1`, {
  sources: [cdk.aws_s3_deployment.Source.asset("resources/dir1")],
  destinationBucket:  destinationBucket,
  destinationKeyPrefix: 'target-path/dir1/',
});

// ★新規追加
new cdk.aws_s3_deployment.BucketDeployment(this, `s3-deploy-dir2`, {
  sources: [cdk.aws_s3_deployment.Source.asset("resources/dir2")],
  destinationBucket:  destinationBucket,
  destinationKeyPrefix: 'target-path/',
});

再度 cdk deploy コマンドでデプロイを行いS3バケットを確認すると、 resources/dir2 の中にあったファイルは target-path/ というprefixでアップロードされていますが、先ほどアップロードした dir1 が削除されています。

20240726_cdk_s3_02

これは、先に説明した通りデフォルトでは s3 sync --delete で実行されているため、 target-path/ というpredfixに対して追記分のファイルのみで sync されることにより、既に存在した target-path/dir1/ のprefixを持つファイルが削除されてしまうことに起因します。

解決方法

方法1

propsの prunefalse にすると --delete オプションが利用されないので、それで対処することができます。

new cdk.aws_s3_deployment.BucketDeployment(this, `s3-deploy-dir2`, {
  sources: [cdk.aws_s3_deployment.Source.asset("resources/dir2")],
  destinationBucket:  destinationBucket,
  destinationKeyPrefix: 'target-path/',
  prune: false,
});

方法2

その他単純な対処として、prefixを変えてしまえば(当然ですが)削除はされません。

new cdk.aws_s3_deployment.BucketDeployment(this, `s3-deploy-dir2`, {
  sources: [cdk.aws_s3_deployment.Source.asset("resources/dir2")],
  destinationBucket:  destinationBucket,
  destinationKeyPrefix: 'target-path-xxx/',
});

最後に

今回は、AWS CDKの aws_s3_deployment.BucketDeployment のpropsである prune の設定値はデフォルトでtrueであることに注意しようという内容について説明させて頂きました

参考になりましたら幸いです。

参考文献

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.